/*
 * ---------------------------------------------------------------------
 * Copyright (c) 2014, 2015 All Right Reserved
 * This software is developed for study and improve coding skill ...
 *
 * Project:  Excellent Coding< EC >
 *
 * Config.h
 * This file for Common software configuration interface implementation.
 *
 * Eamil:   epengao@126.com
 * Author:  Peter Gao
 * Version: Intial first version.
 * --------------------------------------------------------------------
 */

#include "ecConfig.h"
#include "ecStringOP.h"

namespace ec {

ecConfig::ecConfig(const EC_PCHAR pFilePath)
:m_nCount(0)
,m_sFileOP(pFilePath)
{
    if(EC_Err_None == m_sFileOP.Open("rt"))
    {
        ecString pKey;
        ecString pVal;
        ecString sCfgStr;
        EC_CHAR pCfgStr[CONFIG_MAX_ITEM_LENGTH] = {0};

        EC_U32 nReadRet = m_sFileOP.ReadStrLine(pCfgStr, CONFIG_MAX_ITEM_LENGTH);
        while(EC_Err_None == nReadRet)
        {
            sCfgStr = pCfgStr;
            sCfgStr.Trim();
            sCfgStr.TrimEnd();
            if(m_nCount < CONFIG_MAX_ITEM_COUNT)
            {
                pKey = FindKey(sCfgStr.GetAddr());
                pVal = FindVal(sCfgStr.GetAddr());
                if(!pKey.IsNull() /*&& !pVal.IsNull()*/)
                {
                    m_pConfigItem[m_nCount].m_sKey = pKey;
                    m_pConfigItem[m_nCount].m_sVal = pVal;
                    m_nCount++;
                }
            }
            else
                return;

            nReadRet = m_sFileOP.ReadStrLine(pCfgStr, CONFIG_MAX_ITEM_LENGTH);
        };

        m_sFileOP.Close();
    }
}

ecConfig::~ecConfig()
{
}

EC_U32 ecConfig::WriteToFile()
{
    if(EC_Err_None == m_sFileOP.Open("rt"))
    {
        for(EC_U32 i = 0; i < m_nCount; ++i)
        {
            ecString strKey(m_pConfigItem[i].m_sKey);
            ecString strVal(m_pConfigItem[i].m_sVal);
            ecString strLine(strKey + strVal + "\n");
            m_sFileOP.WriteBuffer(strLine.GetAddr(), strLine.Length(), 1);
        };

        m_sFileOP.Close();
    }

    return EC_Err_None;
}

EC_U32 ecConfig::GetItemCount() const
{
    return m_nCount;
}

EC_U32 ecConfig::GetValue(const EC_PCHAR pKey, EC_PCHAR pVal) const
{
    for(EC_U32 i = 0; i < m_nCount; ++i)
    {
        if(0 == ecStrCompare(m_pConfigItem[i].m_sKey.GetAddr(), pKey))
        {
            ecStrCompare(pVal, m_pConfigItem[i].m_sVal.GetAddr());
            return EC_Err_None;
        }
    }

    return EC_Err_DataNotExist;
}

EC_U32 ecConfig::SetValue(const EC_PCHAR pKey, const EC_PCHAR pVal)
{
    for(EC_U32 i = 0; i < m_nCount; ++i)
    {
        if(0 == strcmp(m_pConfigItem[i].m_sKey.GetAddr(), pKey))
        {
            m_pConfigItem[i].m_sVal = pVal;
            return EC_Err_None;
        }
    }

    return EC_Err_DataNotExist;
}

EC_U32 ecConfig::AddItem(const EC_PCHAR pKey, const EC_PCHAR pVal)
{
    if(pKey && (m_nCount < CONFIG_MAX_ITEM_COUNT))
    {
        m_pConfigItem[m_nCount].m_sKey = pKey;
        m_pConfigItem[m_nCount].m_sVal = pVal;
        m_nCount++;
        return EC_Err_None;
    }

    return EC_Err_BadParam;
}

EC_U32 ecConfig::DeleteItem(const EC_PCHAR pKey)
{
    EC_S32 nFindPos = -1;
    for(EC_U32 i = 0; i < m_nCount; ++i)
    {
        if(0 == ecStrCompare(m_pConfigItem[i].m_sKey.GetAddr(), pKey))
        {
            nFindPos = i;
            break;
        }
    }

    if(nFindPos < 0)
        return EC_Err_DataNotExist;
    if((m_nCount-1) == nFindPos)
    {
        m_nCount--;
        return EC_Err_None;
    }

    for(EC_U32 i = nFindPos; i < m_nCount-1; ++i)
        m_pConfigItem[i] = m_pConfigItem[i+1];
    m_nCount--;

    return EC_Err_None;
}

ecString ecConfig::FindKey(const EC_PCHAR pStr) const
{
    ecString sStr(pStr);
    EC_S32 nSize = sStr.FindChar(CONFIG_ASSGINV_CHAR);
    if(nSize >= 0)
        return ecString(pStr, nSize);
    else
    {
        if(pStr && (CONFIG_COMMENT_CHAR == pStr[0]))
            return ecString(CONFIG_COMMENT_STR);
    }

    return ecString();
}

ecString ecConfig::FindVal(const EC_PCHAR pStr) const
{
    ecString sStr(pStr);
    EC_S32 nSize = sStr.FindChar(CONFIG_ASSGINV_CHAR);
    if(nSize >= 0)
    {
        ecString sVal(pStr+nSize+1);
        sVal.Trim();
        return sVal;
    }
    else
        if(pStr && (CONFIG_COMMENT_CHAR == pStr[0]))
            return ecString(pStr+1);

    return ecString();
}

ecConfigItem ecConfig::GetItem(EC_U32 nIndex) const
{
    if(nIndex < m_nCount)
        return m_pConfigItem[nIndex];
    return ecConfigItem();
}
} /* namespace ec */